
#include "stdafx.h"
#include <ccrtrtti.h>
#include "ccrtrtti_defs.h"
#include <typeinfo>
#include <cstdio>

#ifndef UNDER_CE
#include <eh.h>
#else
typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS*);
_CRTIMP _se_translator_function __cdecl _set_se_translator( _se_translator_function _NewPtFunc );
#endif

namespace ccrtrtti
{
	progress_vector_t	progress_vector;
	unwind_map_t			unwind_map;

#if defined(__ENABLE_EHVEC_REPORT_CALLBACK)

	void __eh_vec_ctor_exception_fn( void * array					// pointer to array
										 , unsigned int cpp_obj_size	// element size
										 , int count					// number of elements
										 , int throwing_el				// throwing element
										 )
{
	type_info const * info = 0;
	try {
		info = static_cast<type_info const *>(__RTtypeid( array )); // &typeid( array );
	}
	catch(...)
	{
	}
/*	type_info const * info = 0;
	try 
	{
		rtti::__complete_object_locator_t const * 
			col = rtti::__complete_object_locator_t::from_cpp_object( array );
		info = col->type_descriptor();
	}
	catch(...)
	{
	}*/
	char const * mangled_name = 0;
	if( info != 0 )
		mangled_name = info->raw_name();
	printf("Got exception for array %x[%d] at element [%d] name=%s\n", array, count, throwing_el, mangled_name );
}
#endif

namespace test_1
{
	#include "ccrtrtti_test_decl.h"

	int class_a::counter = 0;
	int class_b::counter = 0;
	int class_c::counter = 0;
	int class_d::counter = 0;
	int class_e::counter = 0;
	int class_f::counter = 0;

	void constructor_impl( class_a * cpp_obj ){}
	void destructor_impl( class_a * cpp_obj ){}

	void constructor_impl( class_b * cpp_obj )
	{
	/*	if( cpp_obj->counter == 1 ) {
			*(int *)0 = 0;
			throw test_class_a_throw_error_2();
		}*/
	}
	void destructor_impl( class_b * cpp_obj ){}

	void constructor_impl( class_c * cpp_obj ){}
	void destructor_impl( class_c * cpp_obj )
	{
		//throw test_error_1();
	}

	void constructor_impl( class_d * cpp_obj ){}
	void destructor_impl( class_d * cpp_obj ){

	}

	void constructor_impl( class_e * cpp_obj ){

	}
	void destructor_impl( class_e * cpp_obj ){}

	void constructor_impl( class_f * cpp_obj ){}
	void destructor_impl( class_f * cpp_obj ){}

	void test()
	{
#if defined(__ENABLE_EHVEC_REPORT_CALLBACK)
		rtti::__set_eh_vec_ctor_exception_callback( &__eh_vec_ctor_exception_fn );
#endif
		printf("Starting test1\n");
		try
		{
			//class_b objb[2];
			class_c obj[2];
			

			//optimized to static_cast by compiler
			class_b *b2 = dynamic_cast<class_b *>(&obj[1]);

			class_c *c3 = dynamic_cast<class_c *>(b2);

			//cross cast
			class_d *d3 = dynamic_cast<class_d *>(c3);
			class_e * e1 = d3;
			class_c *a1 = dynamic_cast<class_c *>(e1);

			//throw test_error_1();
		}
		catch (test_class_a_throw_error_2 const & )
		{
			printf("catch test_class_a_throw_error_2\n");
		}
		catch( test_error_1 const & )
		{
			printf("catch test_error_1\n");
		}
		catch(...)
		{
			printf("catch ...\n");
		}
		
		//dump_progress();
	}

}
}
